namespace Skymate
{
    using Abp.Dependency;

    using Skymate.Lyjt.Core;

    using SuperSocket.Common;
    using SuperSocket.Facility.Protocol;

    public class LightReceiveFilter : BeginEndMarkReceiveFilter<SemaphoreRequestInfo>
    {
        private readonly IProtocolAnalysis _protocolAnalysis;

        /// <summary>
        /// 传入开始标记和结束标记
        /// </summary>
        public LightReceiveFilter()
            : base(ProtocolConst.BeginMark, ProtocolConst.EndMark) 
        {
            this._protocolAnalysis = IocManager.Instance.Resolve<IProtocolAnalysis>();
        }

        protected override SemaphoreRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length)
        {
            var dataBuffer = this._protocolAnalysis.Read(readBuffer);

            if (dataBuffer.Length == 0)
            {
                return new SemaphoreRequestInfo("ERROR", new byte[] { });
            }

            if (dataBuffer.Length < 14)
            {
                return new SemaphoreRequestInfo("ERROR", new byte[] { });
            }

            var version = dataBuffer[0];
            var send = dataBuffer[1];
            var target = dataBuffer[2];
            var datalink = dataBuffer[3];
            var area = dataBuffer[4];
            var intersection = dataBuffer.CloneRange(5, 2);
            var optionType = dataBuffer[7];
            var objectType = dataBuffer[8];
            var retain = dataBuffer.CloneRange(9, 5);

            var data = dataBuffer.CloneRange(14, dataBuffer.Length - 14);

            // 操作类型+对象识别组成命令名称
            return new SemaphoreRequestInfo(
                optionType.ToString("X2") + objectType.ToString("X2"), data)
                       {
                           Version = version,
                           Area = area,
                           DataLink = datalink,
                           Intersection = intersection,
                           Object = objectType,
                           Retain = retain,
                           Send = send,
                           Target = target
                       };
        }
    }
}